import javax.swing.*;
import java.awt.*;
import java.net.URL;

public class GameGUI extends JFrame {
    // 页面
    JTabbedPane tabbedPane;
    JPanel optionsPane;
    JPanel controlPane;
    JScrollPane scrollPane;
    JPanel mapPane;

    // 按钮组件
    JButton clearButton;
    JButton creatButton;
    JButton singleStepButton;
    JButton continuedButton;
    JButton stopButton;

    // 设置页面组件
    JLabel rowLabel;
    JSlider rowSlider;
    JLabel rowValueLabel;
    JLabel colLabel;
    JSlider colSlider;
    JLabel colValueLabel;
    JLabel lifeRatioLabel;
    JSlider lifeRatioSlider;
    JLabel lifeRatioValueLabel;
    JLabel timeLabel;
    JSlider timeSlider;
    JLabel timeValueLabel;

    private GameMap gameMap;
    private GameTimer gameTimer;

    public GameGUI() {
        // 创建窗体
        setTitle("生命游戏");
        // 设置窗体图标
        URL iconURL = GameGUI.class.getClassLoader().getResource("icon.png");
        assert iconURL != null;
        Image icon = new ImageIcon(iconURL).getImage();
        setIconImage(icon);

        // 设置布局管理器
        setLayout(new BorderLayout());
        // 设置窗体大小
        setSize(1200, 800);
        setLocation(0, 0);
        // 设置居中
        setLocationRelativeTo(null);
        // 关闭时退出程序
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        // 设置窗体可见
        setVisible(true);
        // 添加操作页面和显示地图页面
        addTabbedPane();

        scrollPane = new JScrollPane();
        mapPane = new JPanel();
        scrollPane.setViewportView(mapPane);
        add(scrollPane, BorderLayout.CENTER);
    }

    public void init(GameTimer gameTimer, GameMap gameMap) {
        this.gameMap = gameMap;
        this.gameTimer = gameTimer;
    }

    // 添加选项卡页面
    public void addTabbedPane() {
        tabbedPane = new JTabbedPane();

        // 添加控制和选项页面
        addControlPane();
        addOptionsPane();
        tabbedPane.addTab("控制", null, controlPane, "Control");
        tabbedPane.addTab("选项", null, optionsPane, "Options");

        // 将选项卡加入窗体
        add(tabbedPane, BorderLayout.NORTH);
    }

    // 添加控制页面
    public void addControlPane() {
        // 添加按钮
        clearButton = new JButton("清空画面");
        clearButton.addActionListener(e -> {
            clear();
            gameTimer.stop();
        });

        creatButton = new JButton("随机生成");
        creatButton.addActionListener(e -> {
            gameTimer.stop();
            gameMap.init(rowSlider.getValue(), colSlider.getValue());
            gameMap.reset(lifeRatioSlider.getValue());
            updateMap();
        });

        singleStepButton = new JButton("单步演化");
        singleStepButton.addActionListener(e -> {
            gameTimer.stop();
            gameTimer.singleStep();
            updateMap();
        });

        continuedButton = new JButton("持续演化");
        continuedButton.addActionListener(e -> {
            gameTimer.stop();
            gameTimer.start(timeSlider.getValue());
        });

        stopButton = new JButton("暂停");
        stopButton.addActionListener(e -> gameTimer.stop());

        // 按钮页面
        controlPane = new JPanel();

        controlPane.add(clearButton);
        controlPane.add(creatButton);
        controlPane.add(singleStepButton);
        controlPane.add(continuedButton);
        controlPane.add(stopButton);
    }

    // 添加选项页面
    public void addOptionsPane() {
        rowLabel = new JLabel("行数:", SwingConstants.CENTER);
        rowSlider = new JSlider(0, 300, 100);
        rowValueLabel = new JLabel("100");

        colLabel = new JLabel("列数:", SwingConstants.CENTER);
        colSlider = new JSlider(0, 300, 100);
        colValueLabel = new JLabel("100");

        lifeRatioLabel = new JLabel("初始存活率(%):", SwingConstants.CENTER);
        lifeRatioSlider = new JSlider(0, 100, 20);
        lifeRatioValueLabel = new JLabel("20");

        timeLabel = new JLabel("间隔时间(毫秒)", SwingConstants.CENTER);
        timeSlider = new JSlider(0, 5000, 2000);
        timeValueLabel = new JLabel("2000");

        // 设置标签和刻度
        // 设置主刻度间隔
        rowSlider.setMajorTickSpacing(100);
        colSlider.setMajorTickSpacing(100);
        lifeRatioSlider.setMajorTickSpacing(50);
        timeSlider.setMajorTickSpacing(1000);
        // 设置次刻度间隔
        rowSlider.setMinorTickSpacing(50);
        colSlider.setMinorTickSpacing(50);
        lifeRatioSlider.setMinorTickSpacing(10);
        timeSlider.setMinorTickSpacing(500);

        // 设置标签和刻度可见
        rowSlider.setPaintTicks(true);
        rowSlider.setPaintLabels(true);
        colSlider.setPaintTicks(true);
        colSlider.setPaintLabels(true);
        lifeRatioSlider.setPaintTicks(true);
        lifeRatioSlider.setPaintLabels(true);
        timeSlider.setPaintTicks(true);
        timeSlider.setPaintLabels(true);

        // 给滑块添加监听
        addSliderListener(rowSlider, rowValueLabel);
        addSliderListener(colSlider, colValueLabel);
        addSliderListener(lifeRatioSlider, lifeRatioValueLabel);
        addSliderListener(timeSlider, timeValueLabel);

        // 设置页面
        optionsPane = new JPanel(new GridBagLayout());

        // 添加组件到内容面板
        optionsPane.add(rowLabel);
        optionsPane.add(rowValueLabel);
        optionsPane.add(rowSlider);

        optionsPane.add(colLabel);
        optionsPane.add(colValueLabel);
        optionsPane.add(colSlider);

        optionsPane.add(lifeRatioLabel);
        optionsPane.add(lifeRatioValueLabel);
        optionsPane.add(lifeRatioSlider);

        optionsPane.add(timeLabel);
        optionsPane.add(timeValueLabel);
        optionsPane.add(timeSlider);
    }

    // 给滑块添加监听
    private void addSliderListener(JSlider slider, JLabel valueLabel) {
        slider.addChangeListener(e -> valueLabel.setText("" + slider.getValue() + ""));
    }

    // 更新地图
    public void updateMap() {
        mapPane.removeAll();
        mapPane.setLayout(new GridLayout(gameMap.getRows(), gameMap.getCols(), 1, 1));
        for (int i = 0; i < gameMap.getRows(); i++)
            for (int j = 0; j < gameMap.getCols(); j++) {
                if (gameMap.get(i, j) == 1) {
                    JPanel black = new JPanel();
                    black.setBackground(new Color(0, 0, 0));
                    mapPane.add(black);
                } else {
                    JPanel white = new JPanel();
                    white.setBackground(new Color(255, 255, 255));
                    mapPane.add(white);
                }
            }
        mapPane.updateUI();
    }

    // 清除地图
    public void clear() {
        mapPane.removeAll();
        scrollPane.updateUI();
    }

    public int getRows() {
        return rowSlider.getValue();
    }

    public int getCols() {
        return colSlider.getValue();
    }

}
